package com.zhuangfei.hos_timetableview.ability;

import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.interfaces.OnSelectListener;
import com.zhuangfei.hos_timetableview.ResourceTable;
import com.zhuangfei.hos_timetableview.model.MySubject;
import com.zhuangfei.hos_timetableview.model.SubjectRepertory;
import com.zhuangfei.hos_timetableview.utils.ToastUtil;
import com.zhuangfei.timetable.TimetableView;
import com.zhuangfei.timetable.listener.ISchedule;
import com.zhuangfei.timetable.listener.IWeekView;
import com.zhuangfei.timetable.listener.OnSlideBuildAdapter;
import com.zhuangfei.timetable.model.Schedule;
import com.zhuangfei.timetable.utils.ElementUtil;
import com.zhuangfei.timetable.view.WeekView;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.StackLayout;
import ohos.agp.components.Text;
import ohos.agp.utils.Color;

import java.util.List;

/**
 * 基础功能演示：
 * 1.周次选择栏
 * 2.透明背景
 * 3.点击监听
 * 4.颜色分配
 * 5.日期高亮
 * 6.日期计算
 * <p>
 * <p>
 * 该界面的代码注释会比较详细，建议从此处开始看起
 */
public class BaseFuncAbility extends Ability implements Component.ClickedListener {

    private static final String TAG = "BaseFuncActivity";

    // 控件
    TimetableView mTimetableView;
    WeekView mWeekView;

    Button moreButton;
    DirectionalLayout layout;
    Text titleTextView;
    List<MySubject> mySubjects;

    // 记录切换的周次，不一定是当前周
    int target = -1;
    String[] popupMenus;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        setUIContent(ResourceTable.Layout_ability_base_func);
        // 添加表头的include
        StackLayout stInclude = (StackLayout) findComponentById(ResourceTable.Id_st_include);
        stInclude.addComponent(LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_header_base_func, stInclude, false));

        moreButton = (Button) findComponentById(ResourceTable.Id_id_more);
        moreButton.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                showPopmenu();
            }
        });

        mySubjects = SubjectRepertory.loadDefaultSubjects2();
        mySubjects.addAll(SubjectRepertory.loadDefaultSubjects());
        titleTextView = (Text) findComponentById(ResourceTable.Id_id_title);
        layout = (DirectionalLayout) findComponentById(ResourceTable.Id_id_layout);
        layout.setClickedListener(this);
        initTimetableView();
    }

    /**
     * 初始化课程控件
     */
    private void initTimetableView() {
        // 获取控件
        mWeekView = (WeekView) findComponentById(ResourceTable.Id_id_weekview);
        mTimetableView = (TimetableView) findComponentById(ResourceTable.Id_id_timetableView);

        // 设置周次选择属性
        mWeekView.source(mySubjects)
                .curWeek(1)
                .callback(new IWeekView.OnWeekItemClickedListener() {
                    @Override
                    public void onWeekClicked(int week) {
                        int cur = mTimetableView.curWeek();
                        // 更新切换后的日期，从当前周cur->切换的周week
                        mTimetableView.onDateBuildListener()
                                .onUpdateDate(cur, week);
                        mTimetableView.changeWeekOnly(week);
                    }
                })
                .callback(new IWeekView.OnWeekLeftClickedListener() {
                    @Override
                    public void onWeekLeftClicked() {
                        onWeekLeftLayoutClicked();
                    }
                })
                .isShow(false) // 设置隐藏，默认显示
                .showView();

        mTimetableView.source(mySubjects)
                .curWeek(1)
                .curTerm("大三下学期")
                .maxSlideItem(10)
                .monthWidthVp(30)
                // 透明度范围为0->1，0为全透明，1为不透明
                .callback(new ISchedule.OnItemClickListener() {
                    @Override
                    public void onItemClick(Component component, List<Schedule> scheduleList) {
                        display(scheduleList);
                    }
                })
                .callback(new ISchedule.OnItemLongClickListener() {
                    @Override
                    public void onLongClick(Component component, int day, int start) {
                        ToastUtil.showToast(BaseFuncAbility.this, "长按:周" + day + ",第" + start + "节");
                    }
                })
                .callback(new ISchedule.OnWeekChangedListener() {
                    @Override
                    public void onWeekChanged(int curWeek) {
                        titleTextView.setText("第" + curWeek + "周");
                    }
                })
                // 旗标布局点击监听
                .callback(new ISchedule.OnFlaglayoutClickListener() {
                    @Override
                    public void onFlaglayoutClick(int day, int start) {
                        mTimetableView.hideFlaglayout();
                        ToastUtil.showToast(BaseFuncAbility.this, "点击了旗标:周" + (day + 1) + ",第" + start + "节");
                    }
                })
                .showView();
    }

    /**
     * 更新一下，防止因程序在后台时间过长（超过一天）而导致的日期或高亮不准确问题。
     *
     * @param intent 意图
     */
    @Override
    protected void onForeground(Intent intent) {
        super.onForeground(intent);
        mTimetableView.onDateBuildListener().onHighLight();
    }

    /**
     * 周次选择布局的左侧被点击时回调<br/>
     * 对话框修改当前周次
     */
    protected void onWeekLeftLayoutClicked() {
        final String[] items = new String[20];
        int itemCount = mWeekView.itemCount();
        for (int i = 0; i < itemCount; i++) {
            items[i] = "第" + (i + 1) + "周";
        }
        target = -1;
        new XPopup.Builder(getContext())
                .isDarkTheme(true)
                .asCenterList("设置当前周", items,
                        new OnSelectListener() {
                            @Override
                            public void onSelect(int position, String text) {
                                target = position;
                                if (target != -1) {
                                    mWeekView.curWeek(target + 1).updateView();
                                    mTimetableView.changeWeekForce(target + 1);
                                }
                            }
                        })
                .show();
    }

    /**
     * 显示内容
     *
     * @param beans 数据源
     */
    protected void display(List<Schedule> beans) {
        String str = "";
        for (Schedule bean : beans) {
            str += bean.getName() + "," + bean.getWeekList().toString() + "," + bean.getStart() + "," + bean.getStep() + "\n";
        }
        ToastUtil.showToast(this, str);
    }

    /**
     * 显示弹出菜单
     */
    public void showPopmenu() {
        if (popupMenus == null) {
            popupMenus = new String[]{"月份宽度增大", "月份宽度恢复", "隐藏周末", "显示周末", "添加一门课程", "删除一门课程", "隐藏非本周课程", "显示非本周课程",
                    "最大节次8节", "最大节次10节", "最大节次12节", "显示节次时间", "隐藏节次时间", "显示周次选择", "隐藏周次选择"};
        }
        new XPopup.Builder(getContext())
                .hasShadowBg(false)
                .atView(moreButton)
                .asAttachList(popupMenus, null,
                        new OnSelectListener() {
                            @Override
                            public void onSelect(int position, String text) {
                                switch (text) {
                                    case "月份宽度增大":
                                        setMonthWidth();
                                        break;
                                    case "月份宽度恢复":
                                        resetMonthWidth();
                                        break;
                                    case "隐藏周末":
                                        hideWeekends();
                                        break;
                                    case "显示周末":
                                        showWeekends();
                                        break;
                                    case "添加一门课程":
                                        addSubject();
                                        break;
                                    case "删除一门课程":
                                        deleteSubject();
                                        break;
                                    case "隐藏非本周课程":
                                        hideNonThisWeek();
                                        break;
                                    case "显示非本周课程":
                                        showNonThisWeek();
                                        break;
                                    case "最大节次8节":
                                        setMaxItem(8);
                                        break;
                                    case "最大节次10节":
                                        setMaxItem(10);
                                        break;
                                    case "最大节次12节":
                                        setMaxItem(12);
                                        break;
                                    case "显示节次时间":
                                        showTime();
                                        break;
                                    case "隐藏节次时间":
                                        hideTime();
                                        break;
                                    case "显示周次选择":
                                        showWeekView();
                                        break;
                                    case "隐藏周次选择":
                                        hideWeekView();
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }, 0, 0).show();
    }

    @Override
    public void onClick(Component component) {
        if (component.getId() == ResourceTable.Id_id_layout) {
            // 如果周次选择已经显示了，那么将它隐藏，更新课程、日期
            // 否则，显示
            if (mWeekView.isShowing()) {
                hideWeekView();
            } else {
                showWeekView();
            }
        }
    }

    /**
     * 删除课程
     * 内部使用集合维护课程数据，操作集合的方法来操作它即可
     * 最后更新一下视图（全局更新）
     */
    protected void deleteSubject() {
        int size = mTimetableView.dataSource().size();
        int pos = (int) (Math.random() * size);
        if (size > 0) {
            mTimetableView.dataSource().remove(pos);
            mTimetableView.updateView();
        }
    }

    /**
     * 添加课程
     * 内部使用集合维护课程数据，操作集合的方法来操作它即可
     * 最后更新一下视图（全局更新）
     */
    protected void addSubject() {
        List<Schedule> dataSource = mTimetableView.dataSource();
        int size = dataSource.size();
        if (size > 0) {
            Schedule schedule = dataSource.get(0);
            dataSource.add(schedule);
            mTimetableView.updateView();
        }
    }

    /**
     * 隐藏非本周课程
     * 修改了内容的显示，所以必须更新全部（性能不高）
     * 建议：在初始化时设置该属性
     * <p>
     * updateView()被调用后，会重新构建课程，课程会回到当前周
     */
    protected void hideNonThisWeek() {
        mTimetableView.isShowNotCurWeek(false).updateView();
    }

    /**
     * 显示非本周课程
     * 修改了内容的显示，所以必须更新全部（性能不高）
     * 建议：在初始化时设置该属性
     */
    protected void showNonThisWeek() {
        mTimetableView.isShowNotCurWeek(true).updateView();
    }

    /**
     * 设置侧边栏最大节次，只影响侧边栏的绘制，对课程内容无影响
     *
     * @param num 侧边栏最大节次
     */
    protected void setMaxItem(int num) {
        mTimetableView.maxSlideItem(num).updateSlideView();
    }

    /**
     * 显示时间
     * 设置侧边栏构建监听，TimeSlideAdapter是控件实现的可显示时间的侧边栏
     */
    protected void showTime() {
        String[] times = new String[]{
                "8:00", "9:00", "10:10", "11:00",
                "15:00", "16:00", "17:00", "18:00",
                "19:30", "20:30", "21:30", "22:30"
        };
        OnSlideBuildAdapter listener = (OnSlideBuildAdapter) mTimetableView.onSlideBuildListener();
        listener.setTimes(times).setTimeTextColor(Color.BLACK.getValue());
        mTimetableView.updateSlideView();
    }

    /**
     * 隐藏时间
     * 将侧边栏监听置Null后，会默认使用默认的构建方法，即不显示时间
     * 只修改了侧边栏的属性，所以只更新侧边栏即可（性能高），没有必要更新全部（性能低）
     */
    protected void hideTime() {
        mTimetableView.callback((ISchedule.OnSlideBuildListener) null);
        mTimetableView.updateSlideView();
    }

    /**
     * 显示WeekView
     */
    protected void showWeekView() {
        mWeekView.isShow(true);
        titleTextView.setTextColor(new Color(ElementUtil.getColor(this, com.zhuangfei.timetable.ResourceTable.Color_app_red)));
    }

    /**
     * 隐藏WeekView
     */
    protected void hideWeekView() {
        mWeekView.isShow(false);
        titleTextView.setTextColor(new Color(ElementUtil.getColor(this, com.zhuangfei.timetable.ResourceTable.Color_app_course_textcolor_blue)));
        int cur = mTimetableView.curWeek();
        mTimetableView.onDateBuildListener()
                .onUpdateDate(cur, cur);
        mTimetableView.changeWeekOnly(cur);
    }

    /**
     * 设置月份宽度
     */
    private void setMonthWidth() {
        mTimetableView.monthWidthVp(50).updateView();
    }

    /**
     * 设置月份宽度,默认40dp
     */
    private void resetMonthWidth() {
        mTimetableView.monthWidthVp(40).updateView();
    }

    /**
     * 隐藏周末
     */
    private void hideWeekends() {
        mTimetableView.isShowWeekends(false).updateView();
    }

    /**
     * 显示周末
     */
    private void showWeekends() {
        mTimetableView.isShowWeekends(true).updateView();
    }
}
